﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace Twitter.Tests
{
    [TestFixture]
    public class PlainTextMessageBuilderFixture
    {
        [Test]
        public void ShouldGenerateNoMessages()
        {
            var builder = new PlainTextMessageBuilder();
            Assert_Elements(new string[] { }, builder.GetMessages());
        }

        [Test]
        public void SendingFragmentOf110CharsEndsUpAsSingleMessage()
        {
            PlainTextMessageBuilder builder = new PlainTextMessageBuilder();
            builder.AppendFragment(new String('a', 110));
            Assert_Elements(new string[] { new String('a', 110) }, builder.GetMessages());
        }

        [Test]
        public void ShouldClearAppendedFragments()
        {
            var builder = new PlainTextMessageBuilder();
            builder.AppendFragment("Lorem ipsum dolor sit amet.");
            builder.Clear();
            Assert_Elements(new string[] { }, builder.GetMessages());
        }

        [Test]
        public void SendingFragmentOf111CharsEndsUpAsTwoMessages()
        {
            PlainTextMessageBuilder builder = new PlainTextMessageBuilder();
            builder.AppendFragment(new String('a', 111));
            Assert_Elements(new string[]{ 
                new String('a', 106) + " ...", 
                new String('a', 5)},
                builder.GetMessages());
        }

        [Test]
        public void SendingFragmentOf216CharsEndsUpAsTwoMessages()
        {
            PlainTextMessageBuilder builder = new PlainTextMessageBuilder();
            builder.AppendFragment(new String('a', 216));
            Assert_Elements(new string[]{ 
                new String('a', 106) + " ...", 
                new String('a', 110)},
                builder.GetMessages());
        }

        private static void Assert_Elements<T>(IEnumerable<T> expected, IEnumerable<T> actual)
        {
            var exp = new List<T>(expected);
            var act = new List<T>(actual);
            var exp_it = exp.GetEnumerator();
            var act_it = act.GetEnumerator();
            while (exp_it.MoveNext() && act_it.MoveNext())
            {
                Assert.AreEqual(exp_it.Current, act_it.Current);
            }
            Assert.AreEqual(exp.Count, act.Count);
        }
    }
}
